﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MCPlatform.Test.Communicate
{
    public class CRC16Modbus
    {
        private const ushort Polynomial = 0xA001;
        private static ushort[] table = new ushort[256];

        public static ushort ComputeChecksum(byte[] bytes)
        {
            InitialTable();
            ushort crc = 0xFFFF;
            for (int i = 0; i < bytes.Length; ++i)
            {
                byte index = (byte)(crc ^ bytes[i]);
                crc = (ushort)((crc >> 8) ^ table[index]);
            }
            return crc;
        }

        public static byte[] ComputeChecksumBytes(byte[] bytes)
        {
            ushort crc = ComputeChecksum(bytes);
            return BitConverter.GetBytes(crc);
        }

        public static string[] ComputeChecksumString(byte[] bytes)
        {
            ushort crc = ComputeChecksum(bytes);
            var crcBytes = BitConverter.GetBytes(crc);
            string[] crcString = new string[crcBytes.Length];
            for (int i = 0; (i < crcBytes.Length); i++)
            {
                crcString[i] = crcBytes[i].ToString("X2");
            }

            return crcString;

        }

        public static string[] ComputeChecksumString(params string[] hexStrings)
        {

            byte[] bytes = new byte[hexStrings.Length];

            for (int i = 0; i < hexStrings.Length; i++)
            {
            
                bytes[i] = Convert.ToByte(hexStrings[i], 16);

            }

            return ComputeChecksumString(bytes);

        }

        public static string ComputeChecksumToAString(params string[] hexStrings)
        {

            byte[] bytes = new byte[hexStrings.Length];

            for (int i = 0; i < hexStrings.Length; i++)
            {

                bytes[i] = Convert.ToByte(hexStrings[i], 16);

            }
            string[] res = ComputeChecksumString(bytes);
         
            return string.Join("", res);

        }

        public static string[] ByteArrayToStringArray(byte[] bytes)
        {
            string[] crcString = new string[bytes.Length];
            for (int i = 0; (i < bytes.Length); i++)
            {
                crcString[i] = bytes[i].ToString("X2");
            }

            return crcString;
        }

        public static string[] GetAllStrings(params string[] hexStrings)
        {

        
            string[] checkString = ComputeChecksumString(hexStrings);

            List<string> tempList = new List<string>(hexStrings);
            tempList.AddRange(checkString);

            // 如果需要，可以将列表转换回字符串数组
            string[] newArray = tempList.ToArray();

            return newArray;

        }

       
        public static void InitialTable()
        {
            ushort value;
            ushort temp;
            for (ushort i = 0; i < table.Length; ++i)
            {
                value = 0;
                temp = i;
                for (byte j = 0; j < 8; ++j)
                {
                    if (((value ^ temp) & 0x0001) != 0)
                    {
                        value = (ushort)((value >> 1) ^ Polynomial);
                    }
                    else
                    {
                        value >>= 1;
                    }
                    temp >>= 1;
                }
                table[i] = value;
            }
        }
    }
}
